package net.bithappens.hnqe.scratchpad.experiment;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.Random;

import com.ibm.icu.text.SimpleDateFormat;


public class CreateTestDataScript{
	
	private Random random = new Random();
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
	
	private BufferedWriter out;
	
	public CreateTestDataScript(BufferedWriter out) {
		this.out = out;
	}


	public static void main(String[] args) throws IOException {
		
		
		FileWriter fstream = new FileWriter("testData.txt");
		BufferedWriter out = new BufferedWriter(fstream);

		out.write(
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
				"\t<graph datePattern=\"yyyy-MM-dd HH:mm:ss.S\" locale=\"en_US\"\n"+
				"\ttimeStamp=\"2012-01-26 09:00:00.000\" xmlns=\"http://bithappens.net/GraphImportSchema\"\n"+
				"\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"+
				"\txsi:schemaLocation=\"http://bithappens.net/GraphImportSchema graphDataSchema.xsd\">\n\n"
		);
		
		int n = 3000;
		
		int serviceCount = n;
				
		int containerCount = n/50;
		
		int personCount = n/4;
		
		int scuCount = n/8;
		
		
		CreateTestDataScript ctds = new CreateTestDataScript(out);
				
		ctds.createServiceNodes(serviceCount);
		ctds.createContainerNodes(containerCount);
		ctds.createPersonNodes(personCount);
		ctds.createSCUNodes(scuCount);
				
		ctds.createDeployIdNodes(containerCount, serviceCount);
		ctds.createSkillNodes();
		
		ctds.createHasSkillRelation(personCount);
		ctds.createIsDeployedAtWithIdRelation(containerCount, serviceCount);
		ctds.createMaintainsRelation(containerCount, personCount, scuCount);
		ctds.createWorkForSCURelation(personCount, scuCount);
		
		out.write("</graph>");
				
		out.flush();
		
		out.close();
	}
	
	
	
	
	private String getState() {
		int stateProb = random.nextInt(21);
		
		if (stateProb == 19){
			return "blocked";
		}
		
		if (stateProb == 20){
			return "error";	
		}

		return "running";
	}
	
	public void createServiceNodes(int count) throws IOException{
			
		int x = 0;
		while(x < count){
			out.write(
				"<node uri=\"http://sose.com/node/service_"+ x +"\" nodeType=\"Service\">\n" +
					"\t<property name=\"name\" type=\"String\">service_name_" + x + "</property>\n" +
					"\t<property name=\"storagePath\" type=\"String\">storage_path_of_service_"+x+"</property>\n" +
					"\t<property name=\"status\" type=\"String\">" + getState() + "</property>\n" +
				"</node>\n\n"
			);
			x++;
		}
	}


	public void createContainerNodes(int count) throws IOException{
		
		int x = 0;
		while(x < count){
			out.write(
				"<node uri=\"http://sose.com/node/container_"+ x +"\" nodeType=\"Container\">\n" +
					"\t<property name=\"name\" type=\"String\">container_name_" + x + "</property>\n" +
					"\t<property name=\"hostIp\" type=\"String\">192.168."+x/256+"."+ x%256 +"</property>\n" +
					"\t<property name=\"status\" type=\"String\">" + getState() + "</property>\n" +
				"</node>\n\n"
			);
			x++;
		}
	}
	
	
	
	private String getEmployment() {
		switch(random.nextInt(3)){
		case 0: return "admin";
		case 1: return "trainee";
		default: return "team-lead";	
		}
	}
	
	private double getCost() {
		return random.nextInt(10) + 10;
	}
	
	
	public void createPersonNodes(int count) throws IOException{
		int x = 0;
		while(x < count){
			out.write(
				"<node uri=\"http://sose.com/node/person_"+ x +"\" nodeType=\"Person\">\n" +
					"\t<property name=\"name\" type=\"String\">person_name_" + x + "</property>\n" +
					"\t<property name=\"employment\" type=\"String\">"+ getEmployment() +"</property>\n" +
					"\t<property name=\"costPerHour\" type=\"Double\">" + getCost() + "</property>\n" +
				"</node>\n\n"
			);
			x++;
		}
	}
	
	
	public void createSCUNodes(int count) throws IOException{
		int x = 0;
		while(x < count){
			out.write(
				"<node uri=\"http://sose.com/node/scu_"+ x +"\" nodeType=\"SCU\">\n" +
					"\t<property name=\"name\" type=\"String\">scu_name_" + x + "</property>\n" +
				"</node>\n\n"
			);
			x++;
		}
	}
	
	

	
	
	public void createDeployIdNodes(int containerCount, int serviceCount) throws IOException{
		int x = 0;
		while(x < serviceCount / containerCount){
			out.write(
				"<valueNode uri=\"http://sose.com/valueNode/deploy_id/id_"+x+"\" type=\"Integer\">"+x+"</valueNode>\n"
			);
			x++;
		}
		out.write("\n\n");
	}
	
	
	public void createSkillNodes() throws IOException{
		out.write(
			"<valueNode uri=\"http://sose.com/valueNode/skill/hardware\" type=\"String\">hardware</valueNode>" +
			"<valueNode uri=\"http://sose.com/valueNode/skill/software\" type=\"String\">software</valueNode>" +
			"<valueNode uri=\"http://sose.com/valueNode/skill/lead\" type=\"String\">lead</valueNode>"+
			"<valueNode uri=\"http://sose.com/valueNode/skill/communication\" type=\"String\">communication</valueNode>"+
			"<valueNode uri=\"http://sose.com/valueNode/skill/analyze\" type=\"String\">analyze</valueNode>"+
			"<valueNode uri=\"http://sose.com/valueNode/skill/design\" type=\"String\">design</valueNode>\n"
		);
		out.write("\n\n");
	}
	
	
	
	
	private String getSkillURI(int skill) {
		switch(skill){
		case 0: return "http://sose.com/valueNode/skill/hardware";
		case 1: return "http://sose.com/valueNode/skill/software";
		case 2: return "http://sose.com/valueNode/skill/lead";
		case 3: return "http://sose.com/valueNode/skill/communication";
		case 4: return "http://sose.com/valueNode/skill/analyze";
		default: return "http://sose.com/valueNode/skill/design";
		}
	}
	
	public void createHasSkillRelation(int personCount) throws IOException{
		
		int x = 0;
		while(x < personCount){
			int skill = random.nextInt(6);
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/hasSkill/id_"+x+"_1/\" relationType=\"hasSkill\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/person_"+ x+"\"/>\n" +
					"\t<nodeRef nodeUri=\""+getSkillURI(skill)+"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/hasSkill/id_"+x+"_2/\" relationType=\"hasSkill\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/person_"+ x+"\"/>\n" +
					"\t<nodeRef nodeUri=\""+getSkillURI((skill+1)%5)+"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/hasSkill/id_"+x+"_3/\" relationType=\"hasSkill\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/person_"+ x+"\"/>\n" +
					"\t<nodeRef nodeUri=\""+getSkillURI((skill+2)%5)+"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/hasSkill/id_"+x+"_4/\" relationType=\"hasSkill\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/person_"+ x+"\"/>\n" +
					"\t<nodeRef nodeUri=\""+getSkillURI((skill+3)%5)+"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			x++;
		}
	}

	
	public void createIsDeployedAtWithIdRelation(int containerCount, int serviceCount) throws IOException{
		int x = 0;
		int deployStep = serviceCount / containerCount;
		int nextService = 0;
		while(x < containerCount){
			for(int i = 0; i < deployStep; i++){
				long offset = Math.max(random.nextLong(),100000000L);
				Date from = new Date (System.currentTimeMillis()-offset);
				out.write(
					"<hyperEdge uri=\"http://sose.com/relation/isDeployedAtWithId/id_"+x+"_"+i+"/\" relationType=\"isDeployedAtWithId\">\n" +
						"\t<property name=\"since\" type=\"Date\">" + sdf.format(from) + "</property>\n" +
						"\t<nodeRef nodeUri=\"http://sose.com/node/service_"+ nextService +"\"/>\n" +
						"\t<nodeRef nodeUri=\"http://sose.com/node/container_"+ x +"\"/>\n" +
						"\t<nodeRef nodeUri=\"http://sose.com/valueNode/deploy_id/id_" + i  + "\"/>\n" +
					"</hyperEdge>\n\n"
				);
				nextService++;
			}
			x++;
		}
	}
	
	
	public void createMaintainsRelation(int containerCount, int personCount, int scuCount)  throws IOException{
		int x = 0;
		int person1 = random.nextInt(personCount);
		int person2 = (person1 + 1) % personCount;
		int scu = random.nextInt(scuCount);
		while(x < containerCount){
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/maintains/id_"+x+"_1/\" relationType=\"maintains\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/person_"+ person1 +"\"/>\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/container_"+ x +"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/maintains/id_"+x+"_2/\" relationType=\"maintains\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/person_"+ person2 +"\"/>\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/container_"+ x +"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/maintains/id_"+x+"_3/\" relationType=\"maintains\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/scu_"+ scu +"\"/>\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/container_"+ x +"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			x++;
		}
	}
	
	
	public void createWorkForSCURelation(int personCount, int scuCount)  throws IOException{
		int x = 0;
		while(x < personCount){
			int scu = random.nextInt(scuCount);
			
			for(int i = 0; i < 10; i++){
				
				long offset = Math.abs(random.nextLong()) % 100000000L;
				Date from = new Date(System.currentTimeMillis()+offset);
				Date to = new Date(System.currentTimeMillis()+(2*offset));
				
				out.write(
					"<hyperEdge uri=\"http://sose.com/relation/workForScu/id_"+x+"_"+i+"/\" relationType=\"workForSCU\">\n" +
						"\t<property name=\"start\" type=\"Date\">" + sdf.format(from) + "</property>\n" +
						"\t<property name=\"stop\" type=\"Date\">" + sdf.format(to) + "</property>\n" +
						"\t<nodeRef nodeUri=\"http://sose.com/node/person_"+ x +"\"/>\n" +
						"\t<nodeRef nodeUri=\"http://sose.com/node/scu_"+ scu + "\"/>\n" +
					"</hyperEdge>\n\n"
				);	
			}
			x++;
		}
	}
	
	
	
}